﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows;
using System.Xml;
using System.Windows.Input;

namespace SHomeWorkshop.LunarMind
{
    public class FixedTitle : Title
    {
        public FixedTitle(MainWindow editor, Title masterTitle = null)
            : base(editor)
        {
            isFixed = true;
            this.MainTextBlock.Cursor = Cursors.SizeAll;
            index = -1;

            //collapseAdorner.Visibility = Visibility.Hidden;//装饰器会处理，总是不显示。

            if (masterTitle != null)
            {
                this.HigherLevelTitleID = masterTitle.ID;
            }

            this.MainTextBlock.PreviewMouseLeftButtonDown +=
                new System.Windows.Input.MouseButtonEventHandler(MainTextBlock_PreviewMouseLeftButtonDown);
            this.MainTextBlock.PreviewMouseLeftButtonUp +=
                new System.Windows.Input.MouseButtonEventHandler(MainTextBlock_PreviewMouseLeftButtonUp);

            this.CommentTextBlock.PreviewMouseLeftButtonDown +=
                new System.Windows.Input.MouseButtonEventHandler(CommentTextBlock_PreviewMouseLeftButtonDown);
            this.CommentTextBlock.PreviewMouseLeftButtonUp +=
                new System.Windows.Input.MouseButtonEventHandler(CommentTextBlock_PreviewMouseLeftButtonUp);
        }

        void CommentTextBlock_PreviewMouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            SetNewLocation();
        }

        void CommentTextBlock_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            Globals.MainWindow.isDraggingFixedTitle = true;

            Point mousePoint = e.GetPosition(Globals.MainWindow.mainCanvas);

            Globals.MainWindow.SetFixedTitleDraggingSize(
                new Point(mousePoint.X - this.leftTop.X, mousePoint.Y - this.leftTop.Y));
        }

        void MainTextBlock_PreviewMouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            SetNewLocation();
        }

        private void SetNewLocation()
        {
            if (Globals.MainWindow.isDraggingFixedTitle)
            {
                //记载下移动的位置。
                Title higherTitle = this.GetHigherLvelTitle();
                if (higherTitle == null)
                {
                    Globals.MainWindow.isDraggingFixedTitle = false;
                    return;
                }

                Point leftTop = new Point(Canvas.GetLeft(this), Canvas.GetTop(this));

                Point center = new Point(
                    higherTitle.LeftTop.X + higherTitle.ActualWidth / 2 +
                        (higherTitle.Direction == TitleDirection.Right ?
                        higherTitle.IndentWidth : -higherTitle.IndentWidth),
                    higherTitle.LeftTop.Y + higherTitle.ActualHeight / 2);

                Point newLocation;

                if (higherTitle == this.Editor.RootTitle)
                {
                    newLocation = new Point(Canvas.GetLeft(this), Canvas.GetTop(this));
                }
                else
                {
                    newLocation = new Point(leftTop.X - center.X, leftTop.Y - center.Y);
                }

                if (newLocation.X >= this.Location.X - 5 && newLocation.X <= this.Location.X + 5 &&
                    newLocation.Y >= this.Location.Y - 5 && newLocation.Y <= this.Location.Y + 5)
                {
                    this.RefreshLoaction();
                    Globals.MainWindow.isDraggingFixedTitle = false;
                    return;//没移动。
                }

                ModifingItem mi = new ModifingItem()
                {
                    IsNeedRefreshRelations = true,
                    ModifingName = "移动固定标题位置"
                };

                Action actLocation = new Action(this.ID, -1, this.GetType().Name, "Location", this.Location.ToString(),
                    newLocation.ToString());

                this.Location = newLocation;

                mi.Add(actLocation);

                Globals.MainWindow.Do(mi);
                Globals.MainWindow.IsModified = true;

                this.RefreshRelations();

                Globals.MainWindow.isDraggingFixedTitle = false;
            }
        }

        void MainTextBlock_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            Globals.MainWindow.isDraggingFixedTitle = true;

            Point mousePoint = e.GetPosition(Globals.MainWindow.mainCanvas);

            Globals.MainWindow.SetFixedTitleDraggingSize(
                new Point(mousePoint.X - this.leftTop.X, mousePoint.Y - this.leftTop.Y));
        }

        public override void BuildTitle()
        {
            base.BuildTitle();

            try
            {
                XmlAttribute attrLocation = this.XmlData.GetAttribute("Location");
                if (attrLocation != null)
                {
                    this.location = Point.Parse(attrLocation.Value);
                }
            }
            catch (Exception ex)
            {
                Dialogs.LunarMsgBox.MsgBoxShow(Globals.AppName,
                    "FixedTitle的BuildTitle()方法出错。异常信息如下：\r\n",
                    ex.Message, ex.StackTrace, MessageBoxButton.OK, MessageBoxImage.Error,
                    null, MessageBoxResult.OK, Editor);
                return;
            }
        }

        private Point location = new Point(-100, 100);//默认在主标题的左下角。

        internal override void SetLeftTop(double x, double y)
        {
            leftTop.X = x;
            leftTop.Y = y;
        }

        /// <summary>
        /// 与主标题的相对位置。
        /// </summary>
        public Point Location
        {
            get { return location; }
            set
            {
                location = value;
                if (this.XmlData != null)
                {
                    this.XmlData.SetAttribute("Location", value.ToString());
                }
                RefreshLoaction();
            }
        }

        public void RefreshLoaction()
        {
            Title higherTitle = this.GetHigherLvelTitle();

            if (higherTitle == null)
            {
                this.Visibility = Visibility.Hidden;
                return;
            }
            else
            {
                if (higherTitle.BeCollapsed)
                {
                    this.Visibility = Visibility.Hidden;
                    return;
                }
                else
                {
                    this.Visibility = Visibility.Visible;
                }
            }

            if (higherTitle == Editor.RootTitle)//从根标题引出的备注文本块固定位置。
            {
                Canvas.SetLeft(this, location.X);
                Canvas.SetTop(this, location.Y);

                this.SetLeftTop(location.X, location.Y);

                return;
            }

            Rect masterRect = new Rect(higherTitle.LeftTop.X, higherTitle.LeftTop.Y,
                higherTitle.ActualWidth, higherTitle.ActualHeight);

            Point masterCenter = new Point(masterRect.Left + masterRect.Width / 2, masterRect.Top + masterRect.Height / 2);

            Point newLeftTop = new Point(masterCenter.X + location.X +
                (higherTitle.Direction == TitleDirection.Right ? higherTitle.IndentWidth : -higherTitle.IndentWidth),
                masterCenter.Y + location.Y);

            this.SetLeftTop(newLeftTop.X, newLeftTop.Y);

            Canvas.SetLeft(this, newLeftTop.X);
            Canvas.SetTop(this, newLeftTop.Y);

            if (IsMouseOver && Editor != null)
            {
                Editor.RefreshMousePointToTitle(this);
            }
        }

        internal void RefreshRelations()
        {
            if (Editor == null) return;

            foreach (UIElement ue in Editor.mainCanvas.Children)
            {
                Relation r = ue as Relation;
                if (r == null) continue;

                if (r.StartTitleID == this.ID || r.EndTitleID == this.ID)
                {
                    r.RefreshLocation();
                }
            }
        }

        public override void SetProperty(string propertyName, string value)
        {
            base.SetProperty(propertyName, value);

            switch (propertyName)
            {
                case "Location":
                    {
                        this.Location = Point.Parse(value);
                        RefreshLoaction();
                        break;
                    }
            }
        }
    }
}
